


enum ClerkStateEnum ticketTakerStates[5];

int ticketTakerConditionVariables[5];
int ticketTakerLineConditionVariables[5];
int ticketTakerLocks[5];


int ticketTakerLineLock;
int totalTicketLock;
int takingTicketsLock;
int ticketTakerLineCount[5];

int dontGoIn[5];

int numberOfTickets[5];

int numberOfTakerNumbers;
int TakerNumberLock;

/*this is the ticket taker. he wants to be your friend. he will take your troubles and turn them into tickets, which he will hold onto for you while you enjoy a movie. when you exit the theater your troubles - the tickets - will be gone.*/
void TicketTaker(/*int TakerNumber*/)
{
	int TakerNumber;
	
	/*waits movie theater so that everything will only start when their data has been initialized*/
	/*LockAcquire(initialLock);
	LockRelease(initialLock);*/
       
       LockAcquire(TakerNumberLock);
       TakerNumber = numberOfTakerNumbers;
       numberOfTakerNumbers++;
       LockRelease(TakerNumberLock);

	
	
	while(1)
	{
onBreak:
		if(ticketTakerStates[TakerNumber]==on_break)
		{
			Write1("Ticket Taker %i going on break\n",32,1,TakerNumber);
		}
		
		/*Lock the lines*/
		LockAcquire(ticketTakerLineLock);
		LockAcquire(ticketTakerLocks[TakerNumber]);
		
		dontGoIn[TakerNumber]=1;
		

		/*for(int i=0; ticketTakerStates[TakerNumber]==on_break; i++)
		{
			currentThread->Yield();
			if(i==BREAK_LENGTH)
			{
				printf("%s %i coming off of break\n",currentThread->getName(),TakerNumber);
				ticketTakerStates[TakerNumber]=available;
				break;
			}
		}*/
		
		if(ticketTakerStates[TakerNumber]!=on_break)
		{
			
			
			if(ticketTakerLineCount[TakerNumber]>0)	/* If there is a line */
			{
				Write1("Ticket Taker %i has a line length ",34,1,TakerNumber);
				Write1("%i and is signaling a customer\n",32,1,ticketTakerLineCount[TakerNumber]);
				/*
				ticketTakerLineConditionVariables[TakerNumber]->Signal(ticketTakerLineLock);	//Wake up the first person in line
				*/

				Signal(ticketTakerLineConditionVariables[TakerNumber],ticketTakerLineLock);
				ticketTakerLineCount[TakerNumber]--;	/* decrease the line size */
				ticketTakerStates[TakerNumber]=busy;	/* make myself busy */
			}
			else					/* If there isn't a line */
			{
			
				Write1("Ticket Taker %i has no line. I am available for a customer\n",60,1,TakerNumber);
				ticketTakerStates[TakerNumber]=available;	/* Set myself available */

			}
			/*
			ticketTakerLineLock->Release();	// Unlock the lines
			*/
			LockRelease(ticketTakerLineLock);
		}
		else
		{
			LockRelease(ticketTakerLineLock);
		}
		/*
		ticketTakerConditionVariables[TakerNumber]->Wait(ticketTakerLocks[TakerNumber]);	//Wait for a customer to signal
		*/
		Wait(ticketTakerConditionVariables[TakerNumber],ticketTakerLocks[TakerNumber]);
		
		
		LockAcquire(ticketTakerLocks[TakerNumber]);
		if(ticketTakerStates[TakerNumber]==on_break)
		{
			goto onBreak;
		}
		/*
		takingTicketsLock->Acquire();	//Make sure the manager doesn't stop you from taking tickets half way through
		totalTicketLock->Acquire();
		*/

		LockAcquire(takingTicketsLock);
		LockAcquire(totalTicketLock);
		
		
		if((ticketsTaken+numberOfTickets[TakerNumber])>25)
		{
	
		
			Write1("Ticket Taker %i is not allowing the group into the theater. The number of tickets taken is ",91,1,TakerNumber);
			Write1("%i and the group size is ",25,1,ticketsTaken);
			Write1("%i\n",4,1,numberOfTickets[TakerNumber]);
		
		}
		else if(takingTickets) 
		{
			dontGoIn[TakerNumber]=0;
			/*
			ticketTakerLocks[TakerNumber]->Acquire();
			*/
			
			
			
			ticketsTaken+=numberOfTickets[TakerNumber];	/* Increase the total number of tickets taken */
			
			Write1("Ticket Taker %i is allowing the group into the theater. The number of tickets taken is ",87,1,TakerNumber);
			Write1("%i\n",4,1,ticketsTaken);
		}
		else
		{
			Write1("Ticket Taker %i is not allowing the group into the theater. The number of tickets taken is ",91,1,TakerNumber);
			Write1("%i and the group size is ",25,1,ticketsTaken);
			Write1("%i\n",4,1,numberOfTickets[TakerNumber]);
			
		}
		/*
		takingTicketsLock->Release();
		totalTicketLock->Release();
		ticketTakerConditionVariables[TakerNumber]->Signal(ticketTakerLocks[TakerNumber]);	//Alert the customer as to their next action
		ticketTakerConditionVariables[TakerNumber]->Wait(ticketTakerLocks[TakerNumber]);
		*/
		LockRelease(totalTicketLock);
						
		Signal(ticketTakerConditionVariables[TakerNumber],ticketTakerLocks[TakerNumber]);
		LockRelease(ticketTakerLocks[TakerNumber]);

		
		Wait(ticketTakerConditionVariables[TakerNumber], takingTicketsLock);

	}
}


